package cn.jbt.api.admin.service.impl;

import cn.jbt.api.admin.entity.CmsPlaceInfo;
import cn.jbt.api.admin.entity.QCmsPlaceInfo;
import cn.jbt.api.admin.filter.LoginInfoAccessContext;
import cn.jbt.api.admin.repository.CmsPlaceInfoRepository;
import cn.jbt.api.admin.repository.CmsPlaceItemRepository;
import cn.jbt.api.admin.service.ICmsPlaceInfoService;
import com.querydsl.core.types.ExpressionUtils;
import com.querydsl.core.types.Predicate;
import com.querydsl.jpa.impl.JPAQueryFactory;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;

@Service
@Slf4j
@AllArgsConstructor
public class CmsPlaceInfoServiceImpl implements ICmsPlaceInfoService {

    private final JPAQueryFactory jpaQueryFactory;
    private final CmsPlaceInfoRepository cmsPlaceInfoRepository;
    private final CmsPlaceItemRepository cmsPlaceItemRepository;

    @Override
    public List<CmsPlaceInfo> getAll(CmsPlaceInfo cmsPlaceInfo) {
        QCmsPlaceInfo qCmsPlaceInfo = QCmsPlaceInfo.cmsPlaceInfo;

        Predicate predicate = qCmsPlaceInfo.isNotNull().or(qCmsPlaceInfo.isNull());
        if (null != cmsPlaceInfo) {
            if (!StringUtils.isEmpty(cmsPlaceInfo.getName())) {
                predicate = ExpressionUtils.and(predicate,
                        qCmsPlaceInfo.name.contains(cmsPlaceInfo.getName()));
            }
            if (!StringUtils.isEmpty(cmsPlaceInfo.getCode())) {
                predicate = ExpressionUtils.and(predicate,
                        qCmsPlaceInfo.code.contains(cmsPlaceInfo.getCode()));
            }
            if (null != cmsPlaceInfo.getStatus()) {
                predicate = ExpressionUtils.and(predicate,
                        qCmsPlaceInfo.status.eq(cmsPlaceInfo.getStatus()));
            }
        }

        return jpaQueryFactory.selectFrom(qCmsPlaceInfo)
                .where(predicate)
                .orderBy(qCmsPlaceInfo.floor.asc(), qCmsPlaceInfo.orderby.asc(), qCmsPlaceInfo.id.asc())
                .fetch();
    }

    @Override
    public CmsPlaceInfo add(CmsPlaceInfo cmsPlaceInfo) {
        if (null != cmsPlaceInfoRepository.findFirstByCode(cmsPlaceInfo.getCode())) {
            throw new RuntimeException("推荐位编号已存在");
        }

        cmsPlaceInfo.setCreateBy(LoginInfoAccessContext.getLoginInfo().getNickname());
        cmsPlaceInfo.setUpdateBy(cmsPlaceInfo.getCreateBy());
        cmsPlaceInfo = cmsPlaceInfoRepository.save(cmsPlaceInfo);

        if (cmsPlaceInfo.getPid() > 0) {
            CmsPlaceInfo parent = cmsPlaceInfoRepository.findFirstById(cmsPlaceInfo.getPid());
            if (null == parent) {
                throw new RuntimeException("父级未找到");
            }
            cmsPlaceInfo.setFloor(parent.getFloor() + 1);
            cmsPlaceInfo.setNode(parent.getNode() + cmsPlaceInfo.getId() + "/");
        } else {
            cmsPlaceInfo.setFloor(1);
            cmsPlaceInfo.setNode(cmsPlaceInfo.getId() + "/");
        }

        // update floor、node
        return cmsPlaceInfoRepository.save(cmsPlaceInfo);
    }

    @Override
    public CmsPlaceInfo edit(CmsPlaceInfo cmsPlaceInfo) {
        CmsPlaceInfo newCmsPlaceInfo = cmsPlaceInfoRepository.findFirstById(cmsPlaceInfo.getId());
        if (null == newCmsPlaceInfo) {
            throw new RuntimeException("404 Notfound");
        }

        if (null != cmsPlaceInfoRepository.findFirstByCodeAndIdNot(cmsPlaceInfo.getCode(),
                cmsPlaceInfo.getId())) {
            throw new RuntimeException("推荐位编号已存在");
        }

        newCmsPlaceInfo.edit(cmsPlaceInfo);
        newCmsPlaceInfo.setUpdateBy(LoginInfoAccessContext.getLoginInfo().getNickname());
        return cmsPlaceInfoRepository.save(newCmsPlaceInfo);
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void del(List<Long> ids) {

        cmsPlaceInfoRepository.deleteAllByIdInBatch(ids);
        cmsPlaceItemRepository.deleteByPlaceIdIn(ids);

    }
}
